/**
 * Created by user on 2018/4/18.
 */
import Type from './Type'
import { cloneObj, formatSocketMsg } from './Global'
import MaterialPlayer from './MaterialPlayer'
class MaterialController {
  constructor() {
    this.startTime = null
    this.messages = []
    this.imageMsg = []
    this.slideMsg = []
    this.audioTime = 0
    this.interval = null
    this.playedVideoTime = 0
    this.fullTime = 0
    this.cloneSlideMsg = []
    this.images = []
  }


  updateTimeCallback = () => {}

  previewCallback = () => {}

  reset() {
    this.playedVideoTime = 0
    this.setAllUnDone()
  }

  init(startTime, msgs, images, audioTime, callback) {
    if (callback && typeof callback === 'function') {
      this.previewCallback = callback
    }
    this.startTime = startTime
    this.audioTime = audioTime / 1000
    this.images = images
    this.initMsg(msgs)
    this.setClone()
  }

  initMsg(ms) {
    var image_flag = 0, slide_flag = 0
    for(let i in ms) {
      const tmp = Object.assign({}, ms[i]), f = formatSocketMsg(tmp)
      f.done = false
      if (f.type === Type.COMMON_TYPE.MATERIAL_LIVE_IMAGE) {
        f.id = image_flag
        this.imageMsg.push(f)
        image_flag ++
      } else if (f.type === Type.COMMON_TYPE.MATERIAL_LIVE_SLIDE || f.type === Type.COMMON_TYPE.MATERIAL_START_VIDEO) {
        f.id = slide_flag
        this.slideMsg.push(f)
        slide_flag ++
      }
      this.messages.push(f)
    }
  }

  setClone() {
    var videoTime = 0
    for (let i in this.slideMsg) {
      var current = Object.assign({}, this.slideMsg[i])
      current.timestamp += videoTime
      if (current.type === Type.COMMON_TYPE.MATERIAL_START_VIDEO) {
        videoTime += (current.data.video_time * 1000)
      }
      this.cloneSlideMsg.push(current)
    }
    this.fullTime = this.audioTime + (videoTime / 1000)
  }

  setAllUnDone() {
    for (var i in this.slideMsg) {
      this.slideMsg[i].done = false
    }
    for (var i in this.imageMsg) {
      this.imageMsg[i].done = false
    }
  }

  initProgress(p, callback) {
    this.setAllUnDone()
    const diff = this.fullTime * 1000 * p
    if (this.imageMsg.length > 0) {
      var obj = this.getMaxImageMsg(diff)
      callback && callback(obj)
      return obj
    }
    if (this.slideMsg.length > 0) {
      var obj = this.getMaxSlideMsg(diff)
      this.reSetPlayedVideoTime(obj)
      if (obj.playVideo) {
        obj.playVideoCallback = () => {
          this.playedVideoTime += obj.lastTask.data.video_time
        }
      }
      callback && callback(obj)
      return obj
    }
  }

  getMaxImageMsg(diff) {}

  getMaxSlideMsg(diff) {
    let maxUnDoneTask = null
    var len = this.slideMsg.length
    for (let i in this.cloneSlideMsg) {
      var clone_current = this.cloneSlideMsg[i]
      var current = this.slideMsg[i]
      current.done = true
      if (clone_current.timestamp > diff + this.startTime) {
        current.done = false
        maxUnDoneTask = current
        break
      }
    }
    let obj = null
    if (!maxUnDoneTask) {
      let lastDoneTask = this.slideMsg[len - 1]
      let lastCloneDoneTask = this.cloneSlideMsg[len - 1]
      if (lastDoneTask.type === Type.COMMON_TYPE.MATERIAL_LIVE_SLIDE) {
        let realAudioTime = diff - this.getBeforeIndexVideoTime(lastDoneTask.id)
        obj = {
          lastTask: lastDoneTask,
          playVideo: false,
          realAudioTime: realAudioTime,
          realVideoTime: 0,
          type: 'normal',
          hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id)
        }
      }
      if (lastDoneTask.type === Type.COMMON_TYPE.MATERIAL_START_VIDEO) {
        let video_diff_time = diff + this.startTime - lastCloneDoneTask.timestamp
        if (video_diff_time > (lastDoneTask.data.video_time * 1000)) {
          let realAudioTime = diff - this.getBeforeIndexVideoTime(lastDoneTask.id) - lastDoneTask.data.video_time * 1000
          obj = {
            lastTask: lastDoneTask,
            playVideo: false,
            realVideoTime: 0,
            realAudioTime: realAudioTime,
            type: 'normal',
            hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id) + lastDoneTask.data.video_time * 1000
          }
        }
        else {
          let realAudioTime = lastCloneDoneTask.timestamp - this.startTime - this.getBeforeIndexVideoTime(lastDoneTask.id)
          let realVideoTime = video_diff_time
          obj = {
            lastTask: lastDoneTask,
            playVideo: true,
            realVideoTime: realVideoTime,
            realAudioTime: realAudioTime,
            type: 'normal',
            hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id)
          }
        }
      }
    }
    else {
      if (maxUnDoneTask.id == 0) {
        obj = {
          lastTask: null,
          playVideo: false,
          realVideoTime: 0,
          realAudioTime: diff,
          type: 'first',
          hasPlayedVideoTime: 0
        }
      } else {
        let lastDoneTask = this.slideMsg[maxUnDoneTask.id - 1]
        let lastCloneDoneTask = this.cloneSlideMsg[maxUnDoneTask.id - 1]
        if (lastDoneTask.type === Type.COMMON_TYPE.MATERIAL_LIVE_SLIDE) {
          let realAudioTime = diff - this.getBeforeIndexVideoTime(lastDoneTask.id)
          obj = {
            lastTask: lastDoneTask,
            playVideo: false,
            realVideoTime: 0,
            realAudioTime: realAudioTime,
            type: 'normal',
            hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id)
          }
        }
        if (lastDoneTask.type === Type.COMMON_TYPE.MATERIAL_START_VIDEO) {
          let video_diff_time = diff + this.startTime - lastCloneDoneTask.timestamp
          if (video_diff_time >= (lastDoneTask.data.video_time * 1000)) {
            let realAudioTime = diff - this.getBeforeIndexVideoTime(lastDoneTask.id) - (lastDoneTask.data.video_time * 1000)
            obj = {
              lastTask: lastDoneTask,
              playVideo: false,
              realVideoTime: 0,
              realAudioTime: realAudioTime,
              type: 'normal',
              hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id) + (lastDoneTask.data.video_time * 1000)
            }
          } else {
            let realAudioTime = lastCloneDoneTask.timestamp - this.startTime - this.getBeforeIndexVideoTime(lastDoneTask.id)
            let realVideoTime = video_diff_time
            obj = {
              lastTask: lastDoneTask,
              playVideo: true,
              realVideoTime: realVideoTime,
              realAudioTime: realAudioTime,
              type: 'normal',
              hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id)
            }
          }
        }
      }
    }
    obj.realType = 'go_to'
    return obj
  }

  getMaxUnDoneTask(type, diff) {
    var current = null
    var tasks = []
    if(type === 'image') {
      tasks = tasks.concat(this.imageMsg)
    } else if (type === 'slide') {
      tasks = tasks.concat(this.slideMsg)
    }
    for(var i = 0; i < tasks.length; i++) {
      var current_task = tasks[i]
      if (!current_task.done && current_task.timestamp <= diff) {
        current = current_task
        break
      }
    }
    if (!current) {
      return
    }
    this.doTask(current, () => {
      if(current.type === Type.COMMON_TYPE.MATERIAL_START_VIDEO) {
        this.playedVideoTime += current.data.video_time
      }
      current.done = true
    })
  }

  getBeforeIndexVideoTime(taskId) {
    var t= 0
    for (let i in this.slideMsg) {
      let c = this.slideMsg[i]
      if (c.id < taskId && c.type === Type.COMMON_TYPE.MATERIAL_START_VIDEO) {
        t += (c.data.video_time * 1000)
      }
    }
    return t
  }

  reSetPlayedVideoTime(obj) {
    let t = (obj.hasPlayedVideoTime / 1000)
    this.playedVideoTime = t
    return t
  }

  checkTask() {
    var current = parseInt(MaterialPlayer.getCurrentTime() * 1000)
    var diff = current + this.startTime
    if (this.imageMsg.length > 0) {
      this.getMaxUnDoneTask('image', diff)
    }
    if (this.slideMsg.length > 0) {
      this.getMaxUnDoneTask('slide', diff)
    }
    if (current !== 0) {
      this.updateTimeCallback(current/1000 + this.playedVideoTime)
    }
  }

  doTask = (task, callback) => {
    this.previewCallback({
      type: task.type,
      task: task,
      callback: callback
    })
  }

  getUpdateTime() {}

  start() {
    this.stop()
    this.interval = setInterval(() => {
      this.checkTask()
    }, 1000)
    this.checkTask()
  }

  stop() {
    this.interval && clearInterval(this.interval)
  }

  clear() {
    this.startTime = null
    this.messages = []
    this.imageMsg = []
    this.slideMsg = []
    this.audioTime = 0
    this.interval = null
    this.playedVideoTime = 0
    this.fullTime = 0
    this.cloneSlideMsg = []
    this.images = []
  }

  setUpdateTimeCallback(callback) {
    this.updateTimeCallback = callback
  }

  setPreviewCallback(callback) {
    this.previewCallback = callback
  }
}

const controller = new MaterialController()

export default controller
